package tk.mybatis.simple.plugin;

import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;

import java.sql.Statement;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * @author: tianhao.luo@hand-china.com 2021/4/6  10:44
 */
@Intercepts(@Signature(type = ResultSetHandler.class,
        method = "handleResultSets",
        args = {Statement.class}))
public class CameHumpInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        List<Object> list = (List<Object>) invocation.proceed();
        for (Object object : list) {
            if (object instanceof Map) {
                processMap((Map<String, Object>) object);
            }else {
                break;
            }
        }
        return list;
    }


    /**
     * 处理Map类型
     * @param map
     */
    private void processMap(Map<String, Object> map) {
        HashSet<String> keySet = new HashSet<>(map.keySet());
        for (String key : keySet) {
            // 将以大写开头的字符串转换为小写，如果包含下划线也会处理为驼峰
            if ((key.charAt(0) >= 'A' && key.charAt(0) <= 'Z')
                            || key.contains("_")) {
                Object value = map.get(key);
                map.remove(key);
                map.put(underlineToCamelHump(key),value);
            }
        }
    }

    /**
     * 将下划线转换为驼峰
     * @param inputString
     * @return
     */
    public static String underlineToCamelHump(String inputString){
        StringBuilder sb = new StringBuilder();

        boolean nextUpperCase = false;

        for (int i = 0; i < inputString.length(); i++) {
            char c = inputString.charAt(i);
            // 如果是下划线并且已保存的字符长度大于0，
            // 表示下一个字符需要转化为大写
            if (c == '_' && sb.length()>0){
                    nextUpperCase = true;
            }else {
                if (nextUpperCase){
                    sb.append(Character.toUpperCase(c));
                    nextUpperCase = false;
                }else {
                    sb.append(Character.toLowerCase(c));
                }
            }
        }
        return sb.toString();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target,this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
